package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.display.Graphics;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.filters.BlurFilter;
	import flash.filters.DisplacementMapFilter;
	import flash.filters.DisplacementMapFilterMode;
	import flash.geom.Point;
	import flash.media.Camera;
	import flash.media.Video;

	public class ImageWarp extends Sprite
	{
		protected var camera:Camera;
		protected var video:Video;
		
		protected var map:BitmapData;
		protected var mp:Point;
		protected var brush:Shape;
		protected var displace:DisplacementMapFilter;
		
		public var brushSize:Number = 30;
		public var blurStrength:Number = 40;
		public var brushStrength:Number = .05;
		
		public function ImageWarp()
		{
			camera = Camera.getCamera();
			camera.setMode(465, 465, 30);
			video = new Video(465, 465);
			video.attachCamera(camera);
			
			addChild(video);
			
			brush = new Shape();
			brush.filters = [new BlurFilter(blurStrength, blurStrength, 2)];
			mp = new Point();
			
			map = new BitmapData(465, 465, false, 0x800080);
			
			displace = new DisplacementMapFilter(map, new Point(), 4, 1, 100, 100, DisplacementMapFilterMode.CLAMP);
			video.filters = [displace];
			
			stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
		}
		
		protected function onMouseDown(event:MouseEvent):void
		{
			stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
			stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
			
			mp.x = mouseX;
			mp.y = mouseY;
		}
		
		protected function onMove(event:MouseEvent):void
		{
			var dy:Number = mp.y - mouseY;
			var dx:Number = mp.x - mouseX;
			var c:Number = Math.sqrt(dx*dx + dy*dy);
			
			var color:uint = 0xFF;
			
			var g:Graphics = brush.graphics;
			g.clear();
			g.lineStyle(brushSize, color, brushStrength*Math.abs(dx/c));
			g.moveTo(mp.x, mp.y)
			g.lineTo(mouseX, mouseY);
			
			map.draw(brush, null, null, (dx>0)?BlendMode.ADD:BlendMode.SUBTRACT, null, true);
			
			color = 0xFF0000;
			
			g.clear();
			g.lineStyle(brushSize, color, brushStrength*Math.abs(dy/c));
			g.moveTo(mp.x, mp.y)
			g.lineTo(mouseX, mouseY);
			
			map.draw(brush, null, null, (dy>0)?BlendMode.ADD:BlendMode.SUBTRACT, null, true);
			
			displace.mapBitmap = map;
			video.filters = [displace];
			
			mp.x = mouseX;
			mp.y = mouseY;
		}
		
		protected function onMouseUp(event:MouseEvent):void
		{
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
			stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
		}
	}
}